/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#ifndef __G_ASSETS_ARCHIVE_H__
#define __G_ASSETS_ARCHIVE_H__

#include "EnginePrerequisites.h"
#include "FileSystem.h"
#include "GPKArchive.h"

namespace PQEngine
{
	/*GPKArchiveManager composed by many GPKArchive.
	This singleton class must init for one project own one GAssetsAchive.
	Please init this class use the path of the folder that contains .gpk archives.
	Assets archive is two level virtual file system.one level is archives,another is the files in archive.
	GPK archive only have a list of file,do not support folder concept for simplicity.
	*/
	class GPKArchiveManager
	{
	public:
		static const std::string PERSIS_FILE_NAME;//the file mainly contain archive names
		
	protected:
		GPKArchiveManager();
	public:
		static GPKArchiveManager& getSingleton();
		/*Init the asset achive
		@param path - The path of the folder that contains archives.
		*/
		void init(std::string path);
		/*Check whether the archive use name
		@param name - name with no file extension(path will construct inside this function)
		*/
		bool hasArchive(std::string name);

		/*create archive use name
		@param name - name with no file extension(path will construct inside this function)
		*/
		GPKArchive* createArchive(std::string name);

		inline int getNumArchive()
		{
			assert(_inited);
			return _archivePathes.size();
		}

		/*Return the parent folder path that contains archives.
		*/
		inline std::string getPath()
		{
			assert(_inited);
			return _path;
		}


		inline std::string getArchivePath(int index)
		{
			assert(_inited);
			assert(index>=0&&index<_archivePathes.size());
			return _archivePathes[index];
		}

		/*Return archive's name at index position.
		@Note The return name didn't contain extension.
		*/
		std::string getArchiveName(int index);

		/*Add local file to index-th .gpk asset archive
		*/
		bool addArchiveFile(int index,std::string fileName);

		/*Add local file to .gpk asset archive using archive name
		@param name - name with no file extension(path will construct inside this function).
		@param filePath - file path on local file system.
		*/
		bool addArchiveFile(std::string name,std::string filePath);

		/*Return file count in specified asset archive
		*/
		int getNumFile(int index);

		/*Return file name in specified asset archive with specified index
		*/
		std::string getFileName(int archiveIndex,int fileIndex);

		/*Get file in .gpk archives
		@param path The path format is ArchiveName/FileName.
		(Archive name without extension,file name with extension.eg. Character/Sinbad.mesh)
		*/
		GPKFile* getFile(std::string path);

		/*Get file in .gpk archives
		@param path- *.gpk/*.mesh
		*/
		bool hasFile(std::string path);
		
		/*Get archive in assets archive with archive name(only name not the full path)
		If the named archive not exist,this function doesn't create the archive,just return 0.
		*/
		GPKArchive* getArchive(std::string archiveName);

	private:
		void persist();
	private:
		bool _inited;//init indicator
		std::string _path;//path that contains .gpk archives
		std::vector<std::string> _archivePathes;//path in local file system,may only names ok 1 level folder contains all archive
		
	};
}
#define GNgGPKArchiveManager PQEngine::GPKArchiveManager::getSingleton()
#endif
